package com.hugang.juc.blockingqueue;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

/**
 * BlockingQueueDemo
 *
 * @author hg
 * @date 2020/8/21 09:50
 */
public class BlockingQueueDemo {

    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> queue = new ArrayBlockingQueue<>(3);

        //add 返回boolean
        System.out.println(queue.add("a"));
        System.out.println(queue.add("b"));
        System.out.println(queue.add("c"));
        //队列满了则抛异常
//        System.out.println(queue.add("d"));

        //remove 返回队列头的元素并从队列中移除此元素
//        System.out.println(queue.remove());
//        System.out.println(queue.remove());
//        System.out.println(queue.remove());
        //队列为空则抛异常
//        System.out.println(queue.remove());

        //element：检查队列是否为空，若为空，则抛异常，否则返回队列头部的一个元素
        System.out.println(queue.element());

        //offer，往队列中添加元素，返回boolean
        System.out.println(queue.offer("d"));

        //poll 从队列中取出元素，返回队列头部的元素
        System.out.println(queue.poll());
        System.out.println(queue.poll());
//        System.out.println(queue.poll());
        //队列为空则返回null
//        System.out.println(queue.poll());

        //peek 检查队列是否为空，若为空，则返回null，否则返回队列头部的一个元素
        System.out.println("peek ---> "  + queue.peek());

        //put 向队列中添加元素，当队列满了则一直阻塞直到队列有空位
        queue.put("a");
        queue.put("a");
//        queue.put("a");
//        queue.put("a");

        //take 从队列中获取元素，当队列为空则一直阻塞直到队列中有元素
        System.out.println(queue.take());
        System.out.println(queue.take());
        System.out.println(queue.take());
//        System.out.println(queue.take());

        //offer(E,time,unit) 向队列中添加元素，给定超时时间，若超时则返回false
        System.out.println(queue.offer("a", 3, TimeUnit.SECONDS));
        System.out.println(queue.offer("a", 3, TimeUnit.SECONDS));
        System.out.println(queue.offer("a", 3, TimeUnit.SECONDS));
        System.out.println(queue.offer("a", 3, TimeUnit.SECONDS));

        //poll(time,unit) 从队列中获取元素，给定超时时间，若超时则返回null

        System.out.println(queue.poll(3, TimeUnit.SECONDS));
        System.out.println(queue.poll(3, TimeUnit.SECONDS));
        System.out.println(queue.poll(3, TimeUnit.SECONDS));
        System.out.println(queue.poll(3, TimeUnit.SECONDS));


        //SynchronousQueue是一个内部只能包含一个元素的队列。插入元素到队列的线程被阻塞，
        // 直到另一个线程从队列中获取了队列中存储的元素。同样，如果线程尝试获取元素并且当
        // 前不存在任何元素，则该线程将被阻塞，直到线程将元素插入队列。
        SynchronousQueue<Integer> synchronousQueue = new SynchronousQueue<>();

        new Thread(()->{
            for (int i = 0; i < 5; i++) {
                try {
                    synchronousQueue.put(i);
                    System.out.println(Thread.currentThread().getName() + " ---> " + i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"put").start();

        new Thread(()->{
            for (int i = 0; i < 5; i++) {
                try {
                    TimeUnit.SECONDS.sleep(2);
                    System.out.println(Thread.currentThread().getName() + " ---> " + synchronousQueue.take());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"take").start();

    }
}
